{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-colab"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/pathwaycom/pathway/blob/main/examples/notebooks/tutorials/alert-deduplication.ipynb\" target=\"_parent\"><img src=\"https://pathway.com/assets/colab-badge.svg\" alt=\"Run In Colab\" class=\"inline\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "notebook-instructions",
      "source": [
        "# Installing Pathway with Python 3.10+\n",
        "\n",
        "In the cell below, we install Pathway into a Python 3.10+ Linux runtime.\n",
        "\n",
        "> **If you are running in Google Colab, please run the colab notebook (Ctrl+F9)**, disregarding the 'not authored by Google' warning.\n",
        "> \n",
        "> **The installation and loading time is less than 1 minute**.\n"
      ],
      "metadata": {}
    },
    {
      "cell_type": "code",
      "id": "pip-installation-pathway",
      "source": [
        "%%capture --no-display\n",
        "!pip install --prefer-binary pathway"
      ],
      "execution_count": null,
      "outputs": [],
      "metadata": {}
    },
    {
      "cell_type": "code",
      "id": "logging",
      "source": [
        "import logging\n",
        "\n",
        "logging.basicConfig(level=logging.CRITICAL)"
      ],
      "execution_count": null,
      "outputs": [],
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "id": "2",
      "metadata": {
        "lines_to_next_cell": 2
      },
      "source": [
        "# Smart real-time monitoring application with alert deduplication\n",
        "\n",
        "In many monitoring environments, especially those dealing with complex systems, it's common for multiple alerts to be triggered for the same underlying issue. This creates the necessity for alert deduplication, with rules matching specific business needs. In this tutorial we will show how to design and implement such deduplication mechanism in Pathway handling real-time streaming data.\n",
        "\n",
        "For the sake of this tutorial, let's assume we observe a simple stream of floating-point values and our business rule is to notify only whenever the maximal observed value is 30% larger than the previously alerted value.\n",
        "\n",
        "## Sample data\n",
        "Let's generate some static data, which we will convert to a stream later on:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "3",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# GENERATE AND PLOT SAMPLE DATA\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "\n",
        "np.random.seed(10)\n",
        "nb_points = 70\n",
        "\n",
        "# Generate x values\n",
        "x = np.linspace(0, nb_points - 1, nb_points).astype(int)\n",
        "\n",
        "# Generate y values with a globally increasing trend and periodic pattern\n",
        "trend = 0.3 * x**1.1  # Globally increasing trend\n",
        "periodic_pattern = 10 * np.sin(2 * np.pi * x / 20)\n",
        "noise = np.random.normal(0, 1, nb_points)\n",
        "\n",
        "# Combine trend and periodic pattern to create y values\n",
        "y = trend + periodic_pattern + noise\n",
        "\n",
        "\n",
        "# PLOTTING\n",
        "def set_params_plot():\n",
        "    plt.xlabel(\"time\")\n",
        "    plt.ylabel(\"value\")\n",
        "    plt.xticks([], [])\n",
        "    plt.yticks([], [])\n",
        "    plt.title(\"\")\n",
        "\n",
        "\n",
        "# Plot the data points\n",
        "plt.subplot(2, 1, 1)\n",
        "set_params_plot()\n",
        "plt.plot(x, y)\n",
        "\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4",
      "metadata": {},
      "source": [
        "Great! The rule mentioned at the beginning should discover the peaks in this data. Let's see how to use Pathway to create an alerting application notifying us about these peaks.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5",
      "metadata": {},
      "source": [
        "We start by creating a stream out of the above data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6",
      "metadata": {},
      "outputs": [],
      "source": [
        "import pathway as pw\n",
        "\n",
        "# To use advanced features with Pathway Scale, get your free license key from\n",
        "# https://pathway.com/features and paste it below.\n",
        "# To use Pathway Community, comment out the line below.\n",
        "pw.set_license_key(\"demo-license-key-with-telemetry\")\n",
        "\n",
        "\n",
        "value_functions = {\n",
        "    \"time\": lambda i: int(x[i]),\n",
        "    \"value\": lambda i: float(y[i]),\n",
        "}\n",
        "\n",
        "\n",
        "class InputSchema(pw.Schema):\n",
        "    time: int\n",
        "    value: float\n",
        "\n",
        "\n",
        "input = pw.demo.generate_custom_stream(\n",
        "    value_functions,\n",
        "    schema=InputSchema,\n",
        "    nb_rows=len(x),\n",
        "    input_rate=50,\n",
        "    autocommit_duration_ms=10,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "7",
      "metadata": {},
      "source": [
        "To track the maximum value, we could write `input.groupby().reduce(max=pw.reducers.max(input.value))`. Here we want to keep track also *when* this maximum occured, therefore we use the `argmax_rows` utility function."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8",
      "metadata": {
        "lines_to_next_cell": 2
      },
      "outputs": [],
      "source": [
        "reduced = pw.utils.filtering.argmax_rows(input, what=input.value)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9",
      "metadata": {},
      "source": [
        "The newly defined `reduced` table will contain only at most a single row, which will be automatically updated by Pathway with a current maximum. This is not yet what we want - adding alerting callback listening for changes to the above table, would result in excessive notifications.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "10",
      "metadata": {
        "lines_to_next_cell": 2
      },
      "source": [
        "We would want to keep a state with the previous maximum value and see if the change is significant, e.g. if a new maximum is 30% larger than the previous one. Such rule can be expressed as a plain Python function returning `True` if we want to accept new maximum and somehow save it in the state\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "11",
      "metadata": {},
      "outputs": [],
      "source": [
        "def accept_larger_max(new_max: float, prev_max: float) -> bool:\n",
        "    return (\n",
        "        new_max > prev_max * 1.3\n",
        "    )  # your custom business rule for deduplicating alerts"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "12",
      "metadata": {},
      "source": [
        "All you have to do now is to use the `pw.stateful.deduplicate` function to tell Pathway to use your newly defined rule. New values pushed by the stream to the `col` column will be compared to the previously accepted value using the `acceptor` function which we just wrote. Pathway will keep the needed state (i.e. previously accepted value) and perform all the necessary updates for you."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "13",
      "metadata": {},
      "outputs": [],
      "source": [
        "result = pw.stateful.deduplicate(reduced, col=reduced.value, acceptor=accept_larger_max)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "14",
      "metadata": {},
      "source": [
        "Now we can send the alerts to e.g. Slack. We can do it similarily as in the [realtime log monitoring tutorial](/developers/templates/etl/realtime-log-monitoring#scenario-2-sending-the-alert-to-slack) by using `pw.io.subscribe`.\n",
        "\n",
        "Here, for testing purposes, instead of sending an alert, we will store the accepted maxima in the list."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "15",
      "metadata": {},
      "outputs": [],
      "source": [
        "alerts = []\n",
        "\n",
        "\n",
        "def send_alert(key, row, time, is_addition):\n",
        "    if is_addition:\n",
        "        alerts.append(\n",
        "            row\n",
        "        )  # change here to send slack message instead of appending to a list"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "16",
      "metadata": {},
      "outputs": [],
      "source": [
        "pw.io.subscribe(result, send_alert)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "17",
      "metadata": {},
      "source": [
        "Let's run the program. Since the stream we defined is bounded (and we set high `input_rate` in the `generate_custom_stream`), the call to `pw.run` will finish quickly. Hovever, in most usecases, you will be streaming data (e.g. from kafka) indefinitely."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "18",
      "metadata": {},
      "outputs": [],
      "source": [
        "pw.run(monitoring_level=pw.MonitoringLevel.NONE)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "19",
      "metadata": {},
      "source": [
        "Let's see the results and plot them on the dataset, to see what the alerts are:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "20",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[{'time': 0, 'value': 1.331586504129518},\n",
              " {'time': 1, 'value': 4.1054489181478795},\n",
              " {'time': 3, 'value': 9.086296950451466},\n",
              " {'time': 6, 'value': 11.929292906576023},\n",
              " {'time': 23, 'value': 19.916221549411024},\n",
              " {'time': 43, 'value': 26.39125568534823},\n",
              " {'time': 62, 'value': 35.10960077729024}]"
            ]
          },
          "execution_count": null,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "alerts"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "21",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# plot alerted points on top of the data\n",
        "plt.subplot(2, 1, 1)\n",
        "set_params_plot()\n",
        "plt.plot(x, y)\n",
        "plt.plot([r[\"time\"] for r in alerts], [r[\"value\"] for r in alerts], \"x\")\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "22",
      "metadata": {},
      "source": [
        "Great, we won't be overwhelmed with excessive notifications!\n",
        "One downside is that initially we get some alerts, but this is how we defined our deduplication rule! It is easy to fix it by e.g. by considering maxima above a given threshold.\n",
        "\n",
        "The presented deduplication functionality can be used in many other contexts - e.g. in transportation to filter GPS positions of devices so that we keep only relevant measurements which are sufficiently distant apart."
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.14"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}